package top.whysu.edevice.service.system.impl;

import com.alibaba.fastjson.JSON;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Service;
import top.whysu.edevice.dao.system.PermissionDao;
import top.whysu.edevice.dto.page.PagenationDataDTO;
import top.whysu.edevice.dto.page.PagerDTO;
import top.whysu.edevice.dto.system.PermissionDTO;
import top.whysu.edevice.dto.system.PermissionNodeDTO;
import top.whysu.edevice.dto.system.PermissionQueryDTO;
import top.whysu.edevice.po.system.AccountPO;
import top.whysu.edevice.po.system.PermissionPO;
import top.whysu.edevice.service.system.AccountService;
import top.whysu.edevice.service.system.PermissionService;
import top.whysu.edevice.utils.ConverterUtils;
import top.whysu.edevice.utils.PageUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * 系统权限业务实现类
 */
@Service
public class PermissionServiceImpl implements PermissionService {

    @Resource
    private PermissionDao permissionDao;

    @Resource
    private AccountService accountService;

    @Override
    public void insertPermission(PermissionDTO permissionDTO) {
        PermissionPO permissionPO = ConverterUtils.dto2po(permissionDTO, PermissionPO.class);
        permissionDao.insert(permissionPO);
    }

    @Override
    public PagenationDataDTO<PermissionDTO> selectPagePermission(PagerDTO<PermissionQueryDTO> pagerDTO) {
        PageUtils.paging(pagerDTO.getPager());
        LinkedHashMap permissionQueryMap = JSON.parseObject(JSON.toJSONString(pagerDTO.getParams()), LinkedHashMap.class);
        List<PermissionPO> permissionList = permissionDao.selectList(permissionQueryMap);
        //将查询出来的po集合转成DTO集合
        return PageUtils.toPagedResult(permissionList, PermissionDTO.class);
    }

    @Override
    public void updatePermission(PermissionDTO permissionDTO) {
        PermissionPO permissionPO = ConverterUtils.dto2po(permissionDTO, PermissionPO.class);
        permissionDao.update(permissionPO);
    }

    @Override
    public void deletePermission(BigDecimal id) {
        permissionDao.delete(id);
    }

    @Override
    public Map<BigDecimal, List<PermissionDTO>> selectPermissionTree() {
        Subject currentUser = SecurityUtils.getSubject();
        String username = String.valueOf(currentUser.getPrincipal());
        AccountPO account = accountService.selectByUsername(username);
        Map<String, Object> queryMap = new HashMap<>(16);
        queryMap.put("accountId", account.getId());
        queryMap.put("permissionType", "3");
        List<PermissionPO> permissions = selectPermissionsByParams(queryMap);
        // 权限树
        Map<BigDecimal, List<PermissionDTO>> permissionTree = new HashMap<>(16);
        // modId集合
        Set<BigDecimal> modIds = new HashSet<>();
        if (permissions != null && permissions.size() > 0) {
            // 取出菜单的所属模块ID
            for (PermissionPO permission : permissions) {
                modIds.add(permission.getModId());
            }
            for (BigDecimal modId : modIds) {
                List<PermissionPO> modPermissions = new ArrayList<>();
                for (PermissionPO permission : permissions) {
                    if (modId.compareTo(permission.getModId()) == 0) {
                        modPermissions.add(permission);
                    }
                }
                // 构建菜单树
                List<PermissionDTO> modPermissionDTOs = ConverterUtils.po2dto(modPermissions, PermissionDTO.class);
                permissionTree.put(modId, modPermissionDTOs);
            }
        }
        return permissionTree;
    }

    @Override
    public List<PermissionPO> selectPermissionsByParams(Map<String, Object> param) {
        return permissionDao.selectPermissionsByParams(param);
    }

    @Override
    public List<PermissionPO> selectPermissionsByRole(BigDecimal roleId) {
        return permissionDao.selectPermissionsByRole(roleId);
    }

    /***
     * 递归生成树节点
     * @param permissionPO
     * @return
     */
    private List<PermissionNodeDTO> buildPermissionNode(PermissionPO permissionPO) {
        Map<String, Object> queryMap = new HashMap<>(16);
        queryMap.put("modId", permissionPO.getId());
        List<PermissionPO> list = permissionDao.selectList(queryMap);
        if (list.isEmpty()) {
            return null;
        }
        List<PermissionNodeDTO> nodes = new ArrayList<>();
        for (PermissionPO item : list) {
            List<PermissionNodeDTO> childNodes = this.buildPermissionNode(item);

            PermissionNodeDTO node = new PermissionNodeDTO();
            node.setId(item.getId().toString());
            node.setPid(item.getModId().toString());
            node.setText(item.getPermissionTitle());
            node.setChecked(false);
            node.setHasParent(true);
            node.setHasChildren(null != childNodes);
            node.setPageFlag(null != childNodes);
            node.setChildren(childNodes);
            nodes.add(node);
        }
        return nodes;
    }

    @Override
    public List<PermissionNodeDTO> selectAllPermissionTree() {
        // 根据根节点向下生长
        Map<String, Object> queryMap = new HashMap<>(16);
        queryMap.put("permissionType", "0");
        List<PermissionPO> topList = permissionDao.selectList(queryMap);
        PermissionPO topItem = topList.get(0);
        List<PermissionNodeDTO> childNodes = this.buildPermissionNode(topItem);
        // 构建树
        List<PermissionNodeDTO> topTree = new ArrayList<>();
        PermissionNodeDTO topNode = new PermissionNodeDTO();
        topNode.setId(topItem.getId().toString());
        topNode.setText(topItem.getPermissionTitle());
        topNode.setChecked(false);
        topNode.setPageFlag(true);
        topNode.setHasParent(false);
        topNode.setHasChildren(true);
        topNode.setChildren(childNodes);
        topTree.add(topNode);

        return topTree;
    }

    @Override
    public List<PermissionDTO> selectPermissionsByModId(Integer modId) {
        Subject currentUser = SecurityUtils.getSubject();
        String username = String.valueOf(currentUser.getPrincipal());
        AccountPO account = accountService.selectByUsername(username);
        Map<String, Object> queryMap = new HashMap<>(16);
        queryMap.put("accountId", account.getId());
        //queryMap.put("permissionType", "3");
        queryMap.put("modId", modId);
        List<PermissionPO> permissionPOList = selectPermissionsByParams(queryMap);
        List<PermissionDTO> permissionDTOList = ConverterUtils.po2dto(permissionPOList, PermissionDTO.class);
        return permissionDTOList;
    }
}
